const jwt = require('jsonwebtoken');
const fs = require('fs');
const path = require('path');
const createConfig = require('uni-config-center')
const {
	v4: uuidv4
} = require('uuid');

//env静态配置
const envCfg = createConfig({
	pluginId: 'env'
}).config()
//dingtalk静态配置
const dingtalkCfg = createConfig({
	pluginId: 'dingtalk'
}).config()
//STS
const Core = require('@alicloud/pop-core');
//加解密
const CryptoJS = require('crypto-js');
const key = CryptoJS.enc.Utf8.parse("1234123412ABCDEF"); //十六位十六进制数作为密钥
const iv = CryptoJS.enc.Utf8.parse('ABCDEF1234123412'); //十六位十六进制数作为密钥偏移量

// 校验 token，自动续期
function verify_token(token) {
	const publicKey = fs.readFileSync(path.resolve(__dirname, './key/pub.key')).toString();
	return new Promise((resolve, reject) => {
		jwt.verify(token, publicKey, {
			algorithms: ['RS256'],
			complete: false,
			ignoreExpiration: false,
		}, async function(err, payload) {
			if (err) {
				if (err.name == 'TokenExpiredError') {
					resolve({
						code: 401,
						message: 'token已过期'
					});
				} else if (err.name == 'JsonWebTokenError') {
					resolve({
						code: 401,
						message: 'token格式错误'
					});
				} else if (err.name == 'NotBeforeError') {
					resolve({
						code: 401,
						message: 'token还未激活'
					});
				} else {
					resolve({
						code: 401,
						message: '无法校验token'
					});
				}
				return ;
			}
			// payload = {"login_session_key":"0000","iat":1666397186,"nbf":1666397186,"exp":1667001986,"sub":"Token Build"}
			//有效期低于3天，但未过期，则自动刷新token
			var deltaSeconds = (new Date().getTime() - payload.iat * 1000) / 1000;
			if (deltaSeconds < 3 * 24 * 60 * 60) {
				resolve({
					code: 0,
					payload,
					newToken: build_token({
						login_session_key: payload.login_session_key
					})
				})
			} else {
				resolve({
					code: 0,
					payload,
				})
			}
		});
	})
}

// 生成 token
function build_token(payload, expiresIn = "365 days") {
	const privateKey = fs.readFileSync(path.resolve(__dirname, './key/pri.key')).toString();
	const token = jwt.sign({
		...payload
	}, privateKey, {
		// iat:  发布时间，会自动生成
		header: {},
		subject: 'Token Build', //sub 主题
		algorithm: 'RS256', //alg 算法
		expiresIn, //多久过期，"2 days","10h","7d","120ms"。（有它就不要用exp）
		notBefore: '0ms', //nbf 生效不早于多久
	});
	return token;
}

// 获取 OSS的 STS临时签名
async function get_STSToken(ossConfig) {
	var client = new Core({
		accessKeyId: ossConfig.oss_accessKeyId,
		accessKeySecret: ossConfig.oss_accessKeySecret,
		endpoint: ossConfig.oss_endpoint,
		apiVersion: ossConfig.oss_apiVersion,
	});
	var params = {
		"DurationSeconds": ossConfig.oss_DurationSeconds,
		"RoleArn": ossConfig.oss_RoleArn,
		"RoleSessionName": ossConfig.oss_RoleSessionName,
	}
	var requestOption = {
		method: 'POST',
		formatParams: false,
	};
	var result = await client.request('AssumeRole', params, requestOption)
	return result;
}

// AES加密、解密
function decrypt(word) {
	let encryptedHexStr = CryptoJS.enc.Hex.parse(word);
	let srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr);
	let decrypt = CryptoJS.AES.decrypt(srcs, key, {
		iv: iv,
		mode: CryptoJS.mode.CBC,
		padding: CryptoJS.pad.Pkcs7
	});
	let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
	return decryptedStr.toString();
}

function encrypt(word) {
	let srcs = CryptoJS.enc.Utf8.parse(word);
	let encrypted = CryptoJS.AES.encrypt(srcs, key, {
		iv: iv,
		mode: CryptoJS.mode.CBC,
		padding: CryptoJS.pad.Pkcs7
	});
	return encrypted.ciphertext.toString().toUpperCase();
}
  
// 生成uuid
function create_uuid() {
	return uuidv4()
}

// 判断httpMethod
function isHttpMethod(ctx, httpMethod) {
	if (envCfg.debug) return true;
	if (ctx.event.httpMethod == httpMethod){
		if(!ctx.auth){
			console.log("ctx.auth不存在，请检查请求path是否被auth中间件跳过！")
		}
		return true
	}
	return false;
}

// 成功、失败的HTTP响应格式
function success({ data = '', code = 0, message = ''} = {}) {
	return {
		data,
		code,
		message
	}
}
function fail({ data = '', code = 1, message = '' } = {}) {
	return {
		data,
		code,
		message
	}
}

// 是否是super超级管理员-管理资源不受限
function isSuperAdmin(ctx){
	return ctx.auth.tenantId == '0';
}
// 是否是超级管理员-只能管理对应租户的资源
function isAdmin(ctx){
	return ctx.auth.tenantId != '0' && ctx.auth.isAdmin == 1;
}
// 是否有某项权限
function isAuthorities(ctx, authority){
	if(ctx.auth.authorities.includes(authority)) return true;
	return false;
}

/*
* 数据库-工具函数
*/
// 字段是否存在
function isFieldExist(field){
	if(field === undefined) return false;
	if(field === null) return false;
	if(field === "") return false;
	return true;
}
// 拼接 && 查询语句
function whereObj({where, query="", combine="&&"} = {}){
	if(where === '' || where === null || where === undefined) where = '';
	if(where === ''){
		where += query
	}else{
		where += `${combine} ${query}`
	}
	return where;
}






module.exports = {
	//token相关
	verify_token,
	build_token,
	get_STSToken,
	//加解密
	decrypt,
	encrypt,
	//http
	isHttpMethod,
	create_uuid,
	success,
	fail,
	//权限
	isSuperAdmin,
	isAdmin,
	isAuthorities,
	//数据库-工具函数
	isFieldExist,
	whereObj,
	
	
	
}
